package com.ihome.android.util;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader.TileMode;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.view.View;
import android.widget.ImageView;


/**
 * 图片处理帮助类
 * 
 * @author Emerson
 * 
 */
public class ImageHelper {
	private static String		TAG						= ImageHelper.class.getSimpleName();
	public static ImageLoader	imageLoader;
	private static final int	DEFAULT_SIZE			= 100;
	private static final int	DEFAULT_SHADOW_PADDING	= 0X003;

	public static Bitmap createReflectedImage(Bitmap originalBitmap) {
		return createReflectedImage(originalBitmap, -1, -1);
	}


	/**
	 * 根据路径获得突破并压缩返回bitmap用于显示
	 * 
	 * @param imagesrc
	 * @return
	 */
	public static Bitmap getSmallBitmap(String filePath) {
		final BitmapFactory.Options options = new BitmapFactory.Options();
		options.inJustDecodeBounds = true;
		BitmapFactory.decodeFile(filePath, options);

		// Calculate inSampleSize
		options.inSampleSize = calculateInSampleSize(options, 100, 300);

		// Decode bitmap with inSampleSize set
		options.inJustDecodeBounds = false;

		return BitmapFactory.decodeFile(filePath, options);
	}
	
	/**
	 * 计算图片的缩放值
	 * 
	 * @param options
	 * @param reqWidth
	 * @param reqHeight
	 * @return
	 */
	public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
		// Raw height and width of image
		final int height = options.outHeight;
		final int width = options.outWidth;
		int inSampleSize = 1;

		if (height > reqHeight || width > reqWidth) {

			// Calculate ratios of height and width to requested height and  width
			final int heightRatio = Math.round((float) height / (float) reqHeight);
			final int widthRatio = Math.round((float) width / (float) reqWidth);

			/**
			 * Choose the smallest ratio as inSampleSize value, this will
			 * guarantee a final image with both dimensions larger than or equal
			 * to the requested height and width.
			 **/
			inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
		}

		return inSampleSize;
	}
	
	/**
	 * 
	 * 使用这个方法，首先你要将BitmapFactory.Options的inJustDecodeBounds属性设置为true，解析一次图片。
	 * 然后将BitmapFactory.Options连同期望的宽度和高度一起传递到到calculateInSampleSize方法中，就可以得到合适的inSampleSize值了。
	 * 之后再解析一次图片，使用新获取到的inSampleSize值，并把inJustDecodeBounds设置为false，就可以得到压缩后的图片了
	 * 
	 * @param res
	 * @param resId
	 * @param reqWidth
	 * @param reqHeight
	 * @return
	 * @see [类、类#方法、类#成员]
	 */
	public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId, int reqWidth, int reqHeight) {
		// 第一次解析将inJustDecodeBounds设置为true，来获取图片大小  
		final BitmapFactory.Options options = new BitmapFactory.Options();
		options.inJustDecodeBounds = true;
		BitmapFactory.decodeResource(res, resId, options);
		// 调用上面定义的方法计算inSampleSize值  
		options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
		// 使用获取到的inSampleSize值再次解析图片  
		options.inJustDecodeBounds = false;
		return BitmapFactory.decodeResource(res, resId, options);
	}


	public static Bitmap createReflectedImage(Bitmap originalBitmap, int size, int shadowPadding) {
		int width = originalBitmap.getWidth();
		int height = DEFAULT_SIZE;
		if (size > 0) {
			height = size;
		}
		//		if (shadowPadding < 1) {
		//			shadowPadding = DEFAULT_SHADOW_PADDING;
		//		}

		Matrix matrix = new Matrix();
		matrix.preScale(1, -1);

		Bitmap reflectionImage = Bitmap.createBitmap(originalBitmap, 0, 0, width, originalBitmap.getHeight(), matrix, false);
		Bitmap newBitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888);

		Canvas canvas = new Canvas(newBitmap);
		canvas.drawBitmap(reflectionImage, 0, -size - shadowPadding, null);

		Paint paint = new Paint();
		LinearGradient shader = new LinearGradient(0, -height / 2, 0, height, 0xAFffffff, 0x00ffffff, TileMode.CLAMP);
		paint.setShader(shader);
		// Set the Transfer mode to be porter duff and destination in
		paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));
		// Draw a rectangle using the paint with our linear gradient
		canvas.drawRect(0, -height / 2, width, height, paint);

		return newBitmap;
	}

	public static Bitmap createReflectedImage(View view, int size, int shadowPadding) {
		Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888);
		view.draw(new Canvas(bitmap));
		Bitmap retBitmap = createReflectedImage(bitmap, size, shadowPadding);
		if (!bitmap.isRecycled()) {
			bitmap.recycle();
		}
		return retBitmap;
	}

	// 放大缩小图片
	public static Bitmap zoomBitmap(Bitmap bitmap, int w, int h) {
		int width = bitmap.getWidth();
		int height = bitmap.getHeight();
		Matrix matrix = new Matrix();
		float scaleWidht = ((float) w / width);
		float scaleHeight = ((float) h / height);
		matrix.postScale(scaleWidht, scaleHeight);
		Bitmap newbmp = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true);
		return newbmp;
	}

	// 将Drawable转化为Bitmap
	public static Bitmap drawableToBitmap(Drawable drawable) {
		int width = drawable.getIntrinsicWidth();
		int height = drawable.getIntrinsicHeight();
		Bitmap bitmap = Bitmap.createBitmap(width, height, drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565);
		Canvas canvas = new Canvas(bitmap);
		drawable.setBounds(0, 0, width, height);
		drawable.draw(canvas);
		return bitmap;

	}

	// 获得圆角图片的方法
	public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, float roundPx) {

		Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Config.ARGB_8888);
		Canvas canvas = new Canvas(output);

		final int color = 0xff424242;
		final Paint paint = new Paint();
		final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
		final RectF rectF = new RectF(rect);

		paint.setAntiAlias(true);
		canvas.drawARGB(0, 0, 0, 0);
		paint.setColor(color);
		canvas.drawRoundRect(rectF, roundPx, roundPx, paint);

		paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
		canvas.drawBitmap(bitmap, rect, rect, paint);

		return output;
	}

	// 获得带倒影的图片方法
	public static Bitmap createReflectionImageWithOrigin(Bitmap bitmap) {
		final int reflectionGap = 4;
		int width = bitmap.getWidth();
		int height = bitmap.getHeight();

		Matrix matrix = new Matrix();
		matrix.preScale(1, -1);

		Bitmap reflectionImage = Bitmap.createBitmap(bitmap, 0, height / 2, width, height / 2, matrix, false);

		Bitmap bitmapWithReflection = Bitmap.createBitmap(width, (height + height / 2), Config.ARGB_8888);

		Canvas canvas = new Canvas(bitmapWithReflection);
		canvas.drawBitmap(bitmap, 0, 0, null);
		Paint deafalutPaint = new Paint();
		canvas.drawRect(0, height, width, height + reflectionGap, deafalutPaint);

		canvas.drawBitmap(reflectionImage, 0, height + reflectionGap, null);

		Paint paint = new Paint();
		LinearGradient shader = new LinearGradient(0, bitmap.getHeight(), 0, bitmapWithReflection.getHeight() + reflectionGap, 0x70ffffff, 0x00ffffff, TileMode.CLAMP);
		paint.setShader(shader);
		// Set the Transfer mode to be porter duff and destination in
		paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));
		// Draw a rectangle using the paint with our linear gradient
		canvas.drawRect(0, height, width, bitmapWithReflection.getHeight() + reflectionGap, paint);

		return bitmapWithReflection;
	}

	public static Bitmap getRoundedCornerBitmap(Bitmap bitmap) {
		Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Config.ARGB_8888);
		Canvas canvas = new Canvas(output);

		final int color = 0xff424242;
		final Paint paint = new Paint();
		final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
		final RectF rectF = new RectF(rect);
		final float roundPx = 8;

		paint.setAntiAlias(true);
		canvas.drawARGB(0, 0, 0, 0);
		paint.setColor(color);
		canvas.drawRoundRect(rectF, roundPx, roundPx, paint);

		paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
		canvas.drawBitmap(bitmap, rect, rect, paint);

		return output;
	}

	public static byte[] changeBitmapToByte(Bitmap bitmap) {
		byte[] bt = null;
		ByteArrayOutputStream os = new ByteArrayOutputStream();
		// 将Bitmap压缩成PNG编码，质量为100%存储
		bitmap.compress(Bitmap.CompressFormat.PNG, 100, os);
		bt = os.toByteArray();
		return bt;
	}

	public static Bitmap changeByteToBitmap(byte[] bt) {
		Bitmap bitmap = null;
		ByteArrayInputStream in = new ByteArrayInputStream(bt);
		bitmap = BitmapFactory.decodeStream(in);
		return bitmap;
	}

	public static Bitmap convertDrawable2Bitmap(Drawable drawable) {
		BitmapDrawable bd = (BitmapDrawable) drawable;
		return bd.getBitmap();
	}

	public static Drawable convertBitmap2Drawable(Bitmap bitmap) {
		BitmapDrawable bd = new BitmapDrawable(bitmap);
		return bd;
	}

	public static void loadPhonePhoto(final ImageView imagePhoto, byte[] bmp) {
		if (bmp != null) {
			ByteArrayInputStream in = new ByteArrayInputStream(bmp);
			Bitmap bitmap = BitmapFactory.decodeStream(in);
			BitmapDrawable bd = new BitmapDrawable(bitmap);
			imagePhoto.setBackgroundDrawable(bd);
		}
	}
	
	/**
	 * decodes image and scales it to reduce memory consumption
	 * 
	 * @param f
	 * @return
	 */
	public static Bitmap decodeFile(File f) {
		int IMAGE_MAX_SIZE = 1000;

		Bitmap b = null;

		try {
			// Decode image size
			BitmapFactory.Options o = new BitmapFactory.Options();
			o.inJustDecodeBounds = true;

			FileInputStream fis = new FileInputStream(f);
			BitmapFactory.decodeStream(fis, null, o);
			fis.close();

			int scale = 1;
			if (o.outHeight > IMAGE_MAX_SIZE || o.outWidth > IMAGE_MAX_SIZE) {
				scale = (int) Math.pow( 2, (int) Math.round(Math.log(IMAGE_MAX_SIZE 
						/ (double) Math.max(o.outHeight, o.outWidth))
								/ Math.log(0.5)));
			}

			// Decode with inSampleSize
			BitmapFactory.Options o2 = new BitmapFactory.Options();
			o2.inSampleSize = scale;
			fis = new FileInputStream(f);
			b = BitmapFactory.decodeStream(fis, null, o2);
			fis.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

		return b;
	}

	/**
	 * 根据url加载图片并缓存到SoftReference
	 * 
	 * @param view
	 * @param url
	 * @param id
	 */
	public static void loadImage(final Context context, final ImageView view, final String url, final int defaultimage) {
		loadImage(context, view, url, defaultimage, true);
	}

	public static void loadImage(final Context context, final ImageView view, final String url, final int defaultimage, final boolean isBackGroundPic) {
		if (TextUtils.isEmpty(url)) {
			if (isBackGroundPic) {
				view.setBackgroundResource(defaultimage);
			}
			else {
				view.setImageResource(defaultimage);
			}
			return;
		}

		if (imageLoader == null)
			imageLoader = new ImageLoader(context);

		Drawable cacheImage = imageLoader.loadDrawable(url, new ImageLoader.ImageCallback() {
			public void imageLoaded(Drawable imageDrawable) {
				if (url.equals(view.getTag())) {
					if (isBackGroundPic) {
						view.setBackgroundDrawable(imageDrawable);
					}
					else {
						view.setImageDrawable(imageDrawable);
					}
				}
			}
		});

		if (cacheImage != null && url.equals(view.getTag())) {
			if (isBackGroundPic) {
				view.setBackgroundDrawable(cacheImage);
			}
			else {
				view.setImageDrawable(cacheImage);
			}
		}
		else {
			if (isBackGroundPic) {
				view.setBackgroundResource(defaultimage);
			}
			else {
				view.setImageResource(defaultimage);
			}
		}
	}
	
	public static void loadImageFromDisk(final Context context, final ImageView view, final String picPath, final int defaultimage, final boolean isBackGroundPic) {
		if(TextUtils.isEmpty(picPath)){
			if(isBackGroundPic){
				view.setBackgroundResource(defaultimage);
			}else{
				view.setImageResource(defaultimage);
			}
			return;
		}
			
		if (imageLoader == null)
			imageLoader = new ImageLoader(context);

		Drawable cacheImage = imageLoader.loadImageFromDisk(picPath);

		if (cacheImage != null && picPath.equals(view.getTag())) {
			if(isBackGroundPic){
				view.setBackgroundDrawable(cacheImage);
			}else{
				view.setImageDrawable(cacheImage);
			}
		}
		else {
			if(isBackGroundPic){
				view.setBackgroundResource(defaultimage);
			}else{
				view.setImageResource(defaultimage);
			}
		}
	}
}